package com.wans.user.service.impl;

import com.wans.common.redis.RedisPrefix;
import com.wans.common.redis.RedisUtils;
import com.wans.common.result.ResponseResult;
import com.wans.model.user.dos.User;
import com.wans.model.user.dtos.UserDTO;
import com.wans.user.common.em.UserLoginEnum;
import com.wans.user.exception.UserLoginException;
import com.wans.user.mapper.UserMapper;
import com.wans.user.service.UserLoginService;
import com.wans.utils.string.CryptoUtils;
import com.wans.utils.string.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings("all")
public class UserLoginServiceImpl implements UserLoginService {

    @Autowired
    // 操作 user 表
    private UserMapper userMapper;
    @Autowired
    // 操作redis
    private RedisUtils redisUtils;

    /**
     * 用户登录 - 查询是否有该用户
     *
     * @param userLoginInfo 登录信息
     * @return 响应
     */
    @Override
    @Transactional
    public ResponseResult<Void> getUser(UserDTO userLoginInfo) {

        // 检查该用户是否存在
        User user = userMapper.getUserByAccount(userLoginInfo.getAccount());

        if (user == null)
            // 该账号未注册
            throw new UserLoginException(UserLoginEnum.USER_NOT_FOUNT);

        // 检查密码是否匹对
        checkUserToUserLoginInfo(user, userLoginInfo);

        // id缓存进 redis 信息
        redisUtils.set(
                RedisPrefix.USER_LOGIN_SUCCESS.getPrefix() + user.getAccount(),
                user.getId(),
                1,
                TimeUnit.MINUTES
        );

        // 登录业务完成
        return ResponseResult.success(UserLoginEnum.USER_LOGIN_SUCCESS.getMessage());
    }


    /**
     * 检查查询出的数据库中数据是否都存在
     * @param user 根据账号查询的数据库中数据
     * @param userLoginInfo 前端传的登录数据
     * @return 校验是否通过 - true 通过 异常则是未通过
     */
    private boolean checkUserToUserLoginInfo(User user, UserDTO userLoginInfo) {
        // 检查 user 的 id、account、salt、salt2、password 是否缺失
        if (StringUtils.isContainEmpty(user.getId(), user.getAccount(), user.getSalt(), user.getSalt2(), user.getPassword()))
            // 包含有空值
            throw new UserLoginException(UserLoginEnum.USER_DATA_DAMAGE);

        // 检查密码是否正确
        if (user.getPassword().equals(CryptoUtils.hashMD5(userLoginInfo.getPassword(), user.getSalt(), user.getSalt2())))
            // 账号与密码都匹对
            return true;

        throw new UserLoginException(UserLoginEnum.USER_NOT_FOUNT);
    }

}
